Purpose
The query task is used to extract data out of object variables and then reshape that data for an existing task.
Potential Use Case
If you have data that does not fit an existing task's recognized parameter, the query task can reshape that data so that it fits. Using an existing task and then extracting data with a query is more efficient than writing a new task to fit the data. You can also use this task to extract data from a variable for evaluation purposes only.
Properties
Input and output properties are shown below.
Incoming | Type | Required | Description |
---|---|---|---|
pass_on_null |
Boolean | Yes | Controls what the query task returns when the query matches nothing. If true and the query matches nothing, the query task returns the queried data. If false , the most common setting, the query task returns null if it matches nothing. The value can come from a job variable, a static value, or an earlier task's outgoing variable. If the reference task is set to job , the reference variable shows a dropdown of available variable names for selection. If it is set to an earlier task, the reference variable will show the name of that task's outgoing variable. If the reference task is static , the reference variable becomes a pair of radio buttons for selecting true or false. When a query does not have a match and the pass_on_null is false , a null value will be returned but the query will transition to a failure. |
query |
String | Yes | Specifies the query expression. It is similar to how you may perform lookups in JavaScript. Consult the json-query NPM page for usage instructions or review the examples for this task. The query expression can reference a helper function :get() when accessing the value of a property in which the key includes special characters. The colon ( : ) is a special character; it is used to delineate JSON keys and values. If the JSON property key includes a colon, query the property value with the get() helper function. Reference the example below (Query 9) for syntax. The value can come from a job variable, a static value, or an earlier task's outgoing variable. If the reference task is a job variable or earlier task, the reference variable shows a dropdown of available variable names for selection. If the reference task is static, the most common setting, the reference variable becomes a text edit box. |
obj |
Object | Yes | Identifies the data to query. The object can come from a job variable, a static value, or an earlier task's outgoing variable. If the reference task is a job variable or earlier task, the reference variable shows a dropdown of available variable names for selection. If the reference task is static, the reference variable becomes a text edit box. |
Outgoing | Description |
---|---|
return_data |
The query results are assigned to an immutable outgoing variable return_data . Optionally, you can create a job variable from return_data . The immutable outgoing variable return_data remains, and a new mutable job variable is created. When creating a job variable, provide a new name to avoid name conflicts and provide clarity. |
Example 1
In this example, a simple automation was built to obtain data from a remote system using a public API.
On the workflow canvas, a
restCall
task named FetchNumbers-TW19 is set to retrieve numbers information from an available API on the Web. Thequery
task represents the data to search will be provided by the results of therestCall
task.Figure 1: Query Task Workflow Canvas
Double-clicking the
restCall
task opens the task dialog and shows the configuration variables for FetchNumbers-TW19. Of note, the URI points to the API: http://numbersapi.com/random/trivia.Figure 2: RestCall Task Dialog
Next, double-clicking the
Query
task opens the task dialog to show the required input variables. Thequery
parameter is set to search thebody
of the JSON in the available API, and the Reference task for theobj
variable is theresponse
that returns from the FetchNumbers-TW19 task.Figure 3: Query Task Dialog
Once the automation is executed, the
return_data
variable displays a piece of trivia about the number 15 that was randomly generated by querying the publicly available Numbers API.Figure 4: Task Output
Example 2
The following examples illustrate various query expressions against an example object exampleObj
on an IOS platform.
Object
exampleObj = {
"platform": {
"ned": "cisco-ios",
"description": "Cisco IOS Router or Switch"
},
"POPs": {
"ATL": {
"COUNTRY": "US",
"ST": "GEORGIA",
"LN": "ATLANTA",
"cisco-ios-xr": [
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
}
],
"cisco-ios": [
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
},
"ORF": {
"COUNTRY": "US",
"ST": "VIRGINIA",
"LN": "NORFOLK",
"cisco-ios": [
{
"name": "cr1.orf",
"type": "router",
"make": "Cisco",
"model": "7600"
}
],
"juniper-junos": [
{
"name": "er1.orf",
"type": "router",
"make": "Juniper",
"model": "MX10"
}
]
}
}
}
Example 3
When a query has no matching data and pass_on_null
is true
, the workflow will complete successfully. An example workflow is shown below (Figure 5).
Figure 5: Pass On Null (True)
When a query has no matching data and pass_on_null
is false
, the workflow will return an error in the job history. The query will terminate in a failure. An example is shown below (Figure 6).
Figure 6: Pass On Null (True)
Query 1
Extract the points of presence with a query that returns the value for the key POPs
.
{
pass_on_null: true,
query: "POPs",
obj: exampleObj
}
Query 1 Result
{
"ATL": {
"COUNTRY": "US",
"ST": "GEORGIA",
"LN": "ATLANTA",
"cisco-ios-xr": [
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
}
],
"cisco-ios": [
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
},
"ORF": {
"COUNTRY": "US",
"ST": "VIRGINIA",
"LN": "NORFOLK",
"cisco-ios": [
{
"name": "cr1.orf",
"type": "router",
"make": "Cisco",
"model": "7600"
}
],
"juniper-junos": [
{
"name": "er1.orf",
"type": "router",
"make": "Juniper",
"model": "MX10"
}
]
}
}
Query 2
Refine the previous example and access an object's property. Use dot notation to access the key's value.
{
pass_on_null: true,
query: "POPs.ATL.cisco-ios",
obj: exampleObj
}
Query 2 Result
[
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
Query 3
Refine the previous example. Apply a filter using key=value syntax that only matches objects where make
is "Cisco".
{
pass_on_null: true,
query: "POPs.ATL.cisco-ios[make=Cisco]",
obj: exampleObj
}
Notice only the first matched element is returned.
Query 3 Result
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
Query 4
Refine the previous example. Apply a filter to match all objects where make
is "Cisco" with the asterisk operator.
{
pass_on_null: true,
query: "POPs.ATL.cisco-ios[*make=Cisco]",
obj: exampleObj
}
Query 4 Result
[
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
Query 5
Refine the previous example to return all IOS routers in ATL.
{
pass_on_null: true,
query: "POPs.ATL.cisco-ios[*type=router]",
obj: exampleObj
}
Since the asterisk operator's role is to match all, an array is returned even if one or no elements match.
Query 5 Result
[
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
]
Query 6
Perform a compound boolean query with a regular expression.
In this example, we want all IOS devices in ATL with make Cisco and a name that ends in "atl". The ampersand operator is introduced to perform a boolean and evaluation; both conditions must be satisfied. The tilde (~) operator is also introduced to perform a regular expression match.
{
pass_on_null: true,
query: "POPs.ATL.cisco-ios[* make=Cisco & name~/atl$/]",
obj: exampleObj
}
Query 6 Result
[
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
]
Query 7
Perform a deep query. Search through multiple levels of objects or arrays with [**]. Search for any ATL router.
{
pass_on_null: true,
query: "POPs.ATL[**][*type=router]",
obj: exampleObj
}
Query 7 Result
[
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
},
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
]
Query 8
Perform an inner query. Braces de-reference the value of data in the queried object to be used for matching an object's key or an array's element.
Search for all devices in ATL of the NED value found in platform.ned
.
{
pass_on_null: true,
query: "POPs.ATL[{platform.ned}]",
obj: exampleObj
}
Query 8 Result
[
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
Example 3
This example demonstrates a query against exampleObj2
using the get()
helper function.
Object
const exampleObj2 = {
"platform": {
"ned": "cisco-ios",
"description": "Cisco IOS Router or Switch"
},
"POPs": {
"ATL:1": {
"COUNTRY": "US",
"ST": "GEORGIA",
"LN": "ATLANTA",
"cisco-ios-xr": [
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
}
],
"cisco-ios": [
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
},
{
"name": "sw1",
"type": "switch",
"make": "Cisco",
"model": "Catalyt 2960G"
}
]
},
"ORF": {
"COUNTRY": "US",
"ST": "VIRGINIA",
"LN": "NORFOLK",
"cisco-ios": [
{
"name": "cr1.orf",
"type": "router",
"make": "Cisco",
"model": "7600"
}
],
"juniper-junos": [
{
"name": "er1.orf",
"type": "router",
"make": "Juniper",
"model": "MX10"
}
]
}
}
};
Query 1
Perform a query for a property key that includes a special character. The get()
helper function matches keys with special characters.
{
pass_on_null: true,
query: "POPs.:get(ATL:1)[**][*type=router]",
obj: exampleObj2
}
Query 1 Result
[
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
},
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
]
Query 2
Search for any ATL:1
router in the given example object.
{
pass_on_null: true,
query: "POPs.:get(ATL:1)[**][*type=router]",
obj: exampleObj2
}
Query 2 Result
[
{
"name": "cr1.atl",
"type": "router",
"make": "Cisco",
"model": "ASR9K"
},
{
"name": "er1.atl",
"type": "router",
"make": "Cisco",
"model": "3945"
}
]